﻿/*
Copyright (c) 2012 Maksim Gordeev

Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

*/

/*
 * Сделано в SharpDevelop.
 * Пользователь: maxxadm
 * Дата: 07.06.2012
 * Время: 19:20
 * 
 * Для изменения этого шаблона используйте Сервис | Настройка | Кодирование | Правка стандартных заголовков.
 */
using System;
using System.Collections.Generic;
using System.ComponentModel;
using Newtonsoft.Json;

namespace jellybird.core
{
	/*
	 * https://dev.twitter.com/docs/platform-objects/places
	 */
	
	/// <summary>
	/// Places are specific, named locations with corresponding
	///	geo coordinates. They can be attached to Tweets by specifying
	///	a place_id when tweeting. Tweets associated with places
	///	are not necessarily issued from that location but could
	///	also potentially be about that location. Places can be created
	///	and searched for. Tweets can also be found by place_id.
	///	See About Geo Place Attributes for more information.
	/// Consumers of Places should tolerate the addition of new fields
	///	and variance in ordering of fields with ease. Not all fields
	///	appear in all contexts. It is generally safe to consider a nulled
	///	field, an empty set, and the absence of a field as the same thing.
	/// </summary>
	[TypeConverter(typeof(ExpandableObjectConverter))]
	[JsonObject(MemberSerialization.OptIn)]
	public class TwPlace
	{
		public TwPlace()
		{
		}
		
		TwPlaceAttributes attributes;
		
		/// <summary>
		/// Contains a hash of variant information about the place.
		/// </summary>
		[JsonProperty("attributes")]
		public TwPlaceAttributes Attributes {
			get { return attributes; }
			set { attributes = value; }
		}
		
		BoundingBox boundingBox;
		
		/// <summary>
		/// A bounding box of coordinates which encloses this place.
		/// </summary>
		[JsonProperty("bounding_box")]
		public BoundingBox BoundingBox {
			get { return boundingBox; }
			set { boundingBox = value; }
		}
		
		string country;
		
		/// <summary>
		/// Name of the country containing this place.
		/// </summary>
		[JsonProperty("country")]
		public string Country {
			get { return country; }
			set { country = value; }
		}
		
		string countryCode;
		
		/// <summary>
		/// Shortened country code representing the country containing this place.
		/// </summary>
		[JsonProperty("country_code")]
		public string CountryCode {
			get { return countryCode; }
			set { countryCode = value; }
		}
		
		string fullName;
		
		/// <summary>
		/// Full human-readable representation of the place's name.
		/// </summary>
		[JsonProperty("full_name")]
		public string FullName {
			get { return fullName; }
			set { fullName = value; }
		}
		
		string idString;
		
		/// <summary>
		/// ID representing this place. Note that this is represented as a string,
		///	not an integer.
		/// </summary>
		[JsonProperty("id")]
		public string IdString {
			get { return idString; }
			set { idString = value; }
		}
		
		string shortName;
		
		/// <summary>
		/// Short human-readable representation of the place's name.
		/// </summary>
		[JsonProperty("name")]
		public string ShortName {
			get { return shortName; }
			set { shortName = value; }
		}
		
		string placeType;
		
		/// <summary>
		/// The type of location represented by this place.
		/// </summary>
		/// <example>
		/// "place_type":"city"
		/// </example>
		[JsonProperty("place_type")]
		public string PlaceType {
			get { return placeType; }
			set { placeType = value; }
		}
		
		string url;
		
		/// <summary>
		/// URL representing the location of additional place metadata for this place.
		/// </summary>
		[JsonProperty("url")]
		public string Url {
			get { return url; }
			set { url = value; }
		}
	}
	
	/// <summary>
	/// Place Attributes are metadata about places and allow any user or application
	///	to add arbitrary metadata to a place. An attribute is a key-value pair
	///	of arbitrary strings, but with some conventions.
	/// </summary>
	[TypeConverter(typeof(ExpandableObjectConverter))]
	[JsonObject(MemberSerialization.OptIn)]
	public class TwPlaceAttributes:Dictionary<string,string>
	{
		/*
		 * https://dev.twitter.com/docs/about-geo-place-attributes
		 */
		
		[JsonIgnore()]
		public string StreetAddress
		{
			get
			{
				string ret=null;
				this.TryGetValue(PlaceAttributesKnown.StreetAddress,out ret);
				return ret;
			}
			set{this[PlaceAttributesKnown.StreetAddress]=value;}
		}
		
		[JsonIgnore()]
		public string Locality
		{
			get
			{
				string ret=null;
				this.TryGetValue(PlaceAttributesKnown.Locality,out ret);
				return ret;
			}
			set{this[PlaceAttributesKnown.Locality]=value;}
		}
		
		[JsonIgnore()]
		public string Region
		{
			get
			{
				string ret=null;
				this.TryGetValue(PlaceAttributesKnown.Region,out ret);
				return ret;
			}
			set{this[PlaceAttributesKnown.Region]=value;}
		}
		
		[JsonIgnore()]
		public string Iso3
		{
			get
			{
				string ret=null;
				this.TryGetValue(PlaceAttributesKnown.Iso3,out ret);
				return ret;
			}
			set{this[PlaceAttributesKnown.Iso3]=value;}
		}
		
		[JsonIgnore()]
		public string PostalCode
		{
			get
			{
				string ret=null;
				this.TryGetValue(PlaceAttributesKnown.PostalCode,out ret);
				return ret;
			}
			set{this[PlaceAttributesKnown.PostalCode]=value;}
		}
		
		[JsonIgnore()]
		public string Phone
		{
			get
			{
				string ret=null;
				this.TryGetValue(PlaceAttributesKnown.Phone,out ret);
				return ret;
			}
			set{this[PlaceAttributesKnown.Phone]=value;}
		}
			
		[JsonIgnore()]
		public string Twitter
		{
			get
			{
				string ret=null;
				this.TryGetValue(PlaceAttributesKnown.Twitter,out ret);
				return ret;
			}
			set{this[PlaceAttributesKnown.Twitter]=value;}
		}
		
		[JsonIgnore()]
		public string Url
		{
			get
			{
				string ret=null;
				this.TryGetValue(PlaceAttributesKnown.Url,out ret);
				return ret;
			}
			set{this[PlaceAttributesKnown.Url]=value;}
		}
	}
	
	[TypeConverter(typeof(ExpandableObjectConverter))]
	[JsonObject(MemberSerialization.OptIn)]
	public class BoundingBox
	{
		
		/*
		 * http://msdn.microsoft.com/en-us/library/2s05feca(v=vs.71).aspx
		 */
		
		float[][][] coordinates;
		
		/// <summary>
		/// A series of longitude and latitude points, defining a box which
		///	will contain the Place entity this bounding box is related to.
		///	Each point is an array in the form of [longitude, latitude].
		///	Points are grouped into an array per bounding box. Bounding box
		///	arrays are wrapped in one additional array to be compatible
		///	with the polygon notation.
		/// </summary>
		/// <example>
		/// "coordinates":[ [ [2.2241006,48.8155414], [2.4699099,48.8155414], [2.4699099,48.9021461], [2.2241006,48.9021461] ] ]
		/// </example>
		[JsonProperty("coordinates")]
		public float[][][] Coordinates {
			get { return coordinates; }
			set { coordinates = value; }
		}
		
		string boxType;
		
		/// <summary>
		/// The type of data encoded in the coordinates property. This will be
		///	"Polygon" for bounding boxes.
		/// </summary>
		[JsonProperty("type")]
		public string BoxType {
			get { return boxType; }
			set { boxType = value; }
		}
	}
}
